/**
 * 数组工具函数
 */

/**
 * 数组去重
 * @param arr 原始数组
 * @returns 去重后的数组
 */
export const uniqueArray = <T>(arr: T[]): T[] => {
    // 使用 Array.from 替代展开运算符，以避免 Set 迭代的兼容性问题
    return Array.from(new Set(arr))
}

/**
 * 数组分组
 * @param arr 原始数组
 * @param key 分组依据的键名或函数
 * @returns 分组后的对象
 */
export const groupBy = <T>(arr: T[], key: string | ((item: T) => string)): Record<string, T[]> => {
    return arr.reduce(
        (result, item) => {
            const groupKey = typeof key === 'function' ? key(item) : (item as any)[key]
            if (!result[groupKey]) {
                result[groupKey] = []
            }
            result[groupKey].push(item)
            return result
        },
        {} as Record<string, T[]>
    )
}

/**
 * 数组排序
 * @param arr 原始数组
 * @param key 排序依据的键名或函数
 * @param order 排序顺序，默认为升序
 * @returns 排序后的新数组
 */
export const sortArray = <T>(
    arr: T[],
    key: string | ((item: T) => number | string),
    order: 'asc' | 'desc' = 'asc'
): T[] => {
    const newArr = [...arr]
    return newArr.sort((a, b) => {
        const valueA = typeof key === 'function' ? key(a) : (a as any)[key]
        const valueB = typeof key === 'function' ? key(b) : (b as any)[key]

        if (valueA < valueB) return order === 'asc' ? -1 : 1
        if (valueA > valueB) return order === 'asc' ? 1 : -1
        return 0
    })
}

/**
 * 数组转树形结构
 * @param arr 原始数组
 * @param id ID字段名，默认为'id'
 * @param parentId 父ID字段名，默认为'parentId'
 * @param children 子节点字段名，默认为'children'
 * @returns 树形结构数组
 */
export const arrayToTree = <T extends Record<string, any>>(
    arr: T[],
    id = 'id',
    parentId = 'parentId',
    children = 'children'
): T[] => {
    const result: T[] = []
    const map: Record<string | number, T> = {}

    // 创建节点映射
    for (const item of arr) {
        map[item[id]] = { ...item, [children]: [] }
    }

    // 构建树形结构
    for (const item of arr) {
        const node = map[item[id]]
        if (item[parentId] === null || item[parentId] === undefined || item[parentId] === '') {
            // 根节点
            result.push(node)
        } else {
            // 子节点
            if (map[item[parentId]]) {
                map[item[parentId]][children].push(node)
            }
        }
    }

    return result
}

/**
 * 扁平化数组
 * @param arr 嵌套数组
 * @param depth 扁平化深度，默认为Infinity（完全扁平化）
 * @returns 扁平化后的数组
 */
export const flattenArray = <T>(arr: any[], depth = Infinity): T[] => {
    return arr.flat(depth) as T[]
}
